/**
 *
 */
package jp.seraph.same.controller;

import jp.seraph.same.message.MessageUtil;
import jp.seraph.same.model.BlankMotionSessionModel;
import jp.seraph.same.model.DefaultMotionSessionModel;
import jp.seraph.same.model.MotionModel;
import jp.seraph.same.model.MotionSessionModel;

/**
 *
 *
 */
public class DefaultMotionController implements MotionController {
    public DefaultMotionController(MotionModel aModel, MotionManagerController aParentController) {
        mModel = aModel;
        mParentController = aParentController;
    }

    private MotionModel mModel;
    private MotionManagerController mParentController;

    /**
     *
     * @see jp.seraph.same.controller.MotionController#createBlankSession(int, int)
     */
    public MotionSessionModel createBlankSession(int aIndex, int aLength) {
        BlankMotionSessionModel tNewModel = new BlankMotionSessionModel(aLength);

        mModel.add(aIndex, tNewModel);
        return tNewModel;
    }

    /**
     *
     * @see jp.seraph.same.controller.MotionController#createSession(int, String)
     */
    public MotionSessionModel createSession(int aIndex, String aName){
        DefaultMotionSessionModel tNewModel = new DefaultMotionSessionModel(aName);

        mModel.add(aIndex, tNewModel);
        return tNewModel;
    }

    /**
     *
     * @see jp.seraph.same.controller.MotionController#getSession(int)
     */
    public MotionSessionModel getSession(int aIndex) {
        return mModel.get(aIndex);
    }

    /**
     *
     * @see jp.seraph.same.controller.MotionController#removeSession(int)
     */
    public MotionSessionModel removeSession(int aIndex) {
        return mModel.remove(aIndex);
    }

    public MotionSessionModel removeSession(MotionSessionModel aTarget) {
        return mModel.remove(aTarget);
    }

    /**
     *
     * @see jp.seraph.same.controller.MotionController#swapSession(int, int)
     */
    public void swapSession(int i, int j) {
        if(i == j)
            return;

        int tLow;
        int tHigh;
        if(i < j){
            tLow = i;
            tHigh = j;
        }else{
            tLow = j;
            tHigh = j;
        }

        MotionModel tModel = mModel;
        MotionSessionModel tHighModel = tModel.get(tHigh);
        MotionSessionModel tLowModel = tModel.get(tLow);

        tModel.remove(tHigh);
        tModel.remove(tLow);
        tModel.add(tLow, tHighModel);
        tModel.add(tHigh, tLowModel);
    }

    public void delete() {
        mParentController.removeMotion(mModel);
    }

    public void moveDown(MotionSessionModel aSession) {
        int tIndex = this.getIndex(aSession);
        if(tIndex < 0)
            throw new IllegalArgumentException(MessageUtil.sessionNotFound(aSession));

        if(tIndex == mModel.getChildCount() - 1)
            return;
        this.swapSession(tIndex, tIndex + 1);
    }

    public void moveUp(MotionSessionModel aSession) {
        int tIndex = this.getIndex(aSession);
        if(tIndex < 0)
            throw new IllegalArgumentException(MessageUtil.sessionNotFound(aSession));

        if(tIndex == 0)
            return;

        this.swapSession(tIndex, tIndex -1);
    }

    private int getIndex(MotionSessionModel aSession){
        return mModel.getIndex(aSession);
    }

    public void rename(String aNewName) {
        mParentController.renameMotion(mModel.getName(), aNewName);
    }

    /**
     * @see jp.seraph.same.controller.MotionController#renameSession(java.lang.String, java.lang.String)
     */
    public void renameSession(String aOldName, String aNewName) {
        int tIndex = mModel.getIndex(aOldName);
        if(tIndex == -1)
            throw new IllegalArgumentException(MessageUtil.sessionNotFound(aOldName));

        if(mModel.contains(aNewName))
            throw new IllegalArgumentException(MessageUtil.duplicateChildName(aNewName));

        MotionSessionModel tTarget = mModel.remove(tIndex);
        tTarget.setName(aNewName);
        mModel.add(tIndex, tTarget);
    }
}
